home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MISC.SWG / 0007_LONGJUMP.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  3KB  |  62 lines

  1. Unit LongJump;
  2.  
  3. { This Unit permits a long jump from deeply nested Procedures/Functions back }
  4. { to a predetermined starting point.                                         }
  5.  
  6. { Whilst the purists may shudder at such a practice there are times when such}
  7. { an ability can be exceedingly useful.  An example of such a time is in a   }
  8. { BBS Program when the carrier may be lost unexpectedly whilst a user is on  }
  9. { line and the requirement is to "back out" to the initialisation reoutines  }
  10. { at the start of the Program.                                               }
  11.  
  12. { to use the facility, it is required that a call be made to the SetJump     }
  13. { Function at the point to where you wish the execution to resume after a    }
  14. { long jump. When the time comes to return to that point call FarJump.       }
  15.  
  16. { if you are an inexperienced Programmer, I do not recommend that this Unit  }
  17. { be used For other than experimentation.  Usually there are better ways to  }
  18. { achieve what you want to do by proper planning and structuring.  It is     }
  19. { rare to find a well written Program that will need such and ability.       }
  20.  
  21. Interface
  22.  
  23. Const
  24.   normal = -1;                         { return was not from a LongJump call }
  25. Type
  26.   jumpType = Record                        { the data need For a return jump }
  27.                 bp,sp,cs,ip : Word;
  28.              end;
  29.  
  30. Function  SetJump(Var JumpData : jumpType): Integer;
  31. Procedure FarJump(JumpData : jumpType; IDInfo : Integer);
  32.  
  33. Implementation
  34.  
  35. Type
  36.   WordPtr = ^Word;
  37.  
  38. Function SetJump(Var JumpData : jumpType): Integer;
  39.   begin                     { store the return address (the old bp register) }
  40.     JumpData.bp := WordPtr(ptr(SSeg,SPtr+2))^;
  41.     JumpData.ip := WordPtr(ptr(SSeg,SPtr+4))^;
  42.     JumpData.cs := WordPtr(ptr(SSeg,SPtr+6))^;
  43.     JumpData.SP := SPtr;
  44.     SetJump := normal;                { show that this is not a FarJump call }
  45.   end;  { SetJump }
  46.  
  47. Procedure FarJump(JumpData : jumpType; IDInfo : Integer );
  48.   begin
  49.     { change the return address of the calling routine of the stack so that  }
  50.     { a return can be made to the caller of SetJump                          }
  51.     { Use IDInfo as an identifier of the routine the jump occurred from      }
  52.     WordPtr(ptr(SSeg,JumpData.SP))^   := JumpData.bp;
  53.     WordPtr(ptr(SSeg,JumpData.SP+2))^ := JumpData.ip;
  54.     WordPtr(ptr(SSeg,JumpData.SP+4))^ := JumpData.cs;
  55.     Inline($8b/$46/$06);                                     { mov ax,[bp+6] }
  56.     Inline($8b/$ae/$fa/$ff);                                 { mov bp,[bp-6] }
  57.   end;  { FarJump }
  58.  
  59. end.  { LongJump }
  60.  
  61.  
  62.